<?php

/*
 * This file is part of the php-phantomjs.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Ling\PhantomJs\Http;

use Ling\PhantomJs\Exception\InvalidMethodException;
use Ling\PhantomJs\Exception\NotWritableException;

/**
 * PHP PhantomJs.
 *
 * @author Jon Wenmoth <contact@Ling.me>
 */
class CaptureRequest extends AbstractRequest
    implements CaptureRequestInterface
{
    /**
     * Request type.
     *
     * @var string
     */
    protected string $type;

    /**
     * File to save output.
     *
     * @var string
     */
    protected string $outputFile;

    /**
     * Rect top.
     *
     * @var int
     */
    protected int $rectTop;

    /**
     * Rect left.
     *
     * @var int
     */
    protected int $rectLeft;

    /**
     * Rect width.
     *
     * @var int
     */
    protected int $rectWidth;

    /**
     * Rect height.
     *
     * @var int
     */
    protected int $rectHeight;

    /**
     * Capture Format.
     *
     * @var string
     */
    protected string $format;

    /**
     * Capture Quality.
     *
     * @var int
     */
    protected int $quality;

    /**
     * Internal constructor.
     *
     * @param string|null $url (default: null)
     * @param string $method (default: RequestInterface::METHOD_GET)
     * @param int $timeout (default: 5000)
     * @throws InvalidMethodException
     */
    public function __construct(string $url = null, string $method = RequestInterface::METHOD_GET, int $timeout = 5000)
    {
        parent::__construct($url, $method, $timeout);

        $this->rectTop = 0;
        $this->rectLeft = 0;
        $this->rectWidth = 0;
        $this->rectHeight = 0;
        $this->format = 'jpeg';
        $this->quality = 75;
    }

    /**
     * Get request type.
     *
     * @return string
     */
    public function getType(): string
    {
        if (!$this->type) {
            return RequestInterface::REQUEST_TYPE_CAPTURE;
        }

        return $this->type;
    }

    /**
     * Set request type.
     *
     * @param string $type
     *
     * @return AbstractRequest
     */
    public function setType(string $type): AbstractRequest
    {
        $this->type = $type;

        return $this;
    }

    /**
     * Set viewport size.
     *
     * @param int $width
     * @param int $height
     * @param int $top (default: 0)
     * @param int $left (default: 0)
     * @return CaptureRequest
     */
    public function setCaptureDimensions(int $width, int $height, int $top = 0, int $left = 0): CaptureRequest
    {
        $this->rectWidth = $width;
        $this->rectHeight = $height;
        $this->rectTop = $top;
        $this->rectLeft = $left;

        return $this;
    }

    /**
     * Get rect top.
     *
     * @return int
     */
    public function getRectTop(): int
    {
        return $this->rectTop;
    }

    /**
     * Get rect left.
     *
     * @return int
     */
    public function getRectLeft(): int
    {
        return $this->rectLeft;
    }

    /**
     * Get rect width.
     *
     * @return int
     */
    public function getRectWidth(): int
    {
        return $this->rectWidth;
    }

    /**
     * Get rect height.
     *
     * @return int
     */
    public function getRectHeight(): int
    {
        return $this->rectHeight;
    }

    /**
     * Set file to save output.
     *
     * @param string $file
     *
     * @return CaptureRequest
     * @throws NotWritableException
     *
     */
    public function setOutputFile(string $file): CaptureRequest
    {
        if (!is_writable(dirname($file))) {
            throw new NotWritableException(sprintf('Output file is not writeable by PhantomJs: %s', $file));
        }

        $this->outputFile = $file;

        return $this;
    }

    /**
     * Get output file.
     *
     * @return string
     */
    public function getOutputFile(): string
    {
        return $this->outputFile;
    }

    /**
     * Get image format of the capture.
     *
     * @return string
     */
    public function getFormat(): string
    {
        return $this->format;
    }

    /**
     * Set image format of capture.
     * options: pdf, png, jpeg, bmp, ppm, gif.
     *
     * @param string $format
     * @return CaptureRequest
     */
    public function setFormat(string $format): CaptureRequest
    {
        $this->format = $format;
        return $this;
    }

    /**
     * Get quality of capture.
     *
     * @return int
     */
    public function getQuality(): int
    {
        return $this->quality;
    }

    /**
     * Set quality of the capture.
     * example: 0 - 100.
     *
     * @param int $quality
     * @return CaptureRequest
     */
    public function setQuality(int $quality): CaptureRequest
    {
        $this->quality = $quality;
        return $this;
    }
}
